package com.gateway.app.lb;

import com.alibaba.fastjson2.JSON;
import com.gateway.app.common.IpReq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@RestController
public class HealthController {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private GatewayProperties gatewayProperties;
    /**
     * 健康检查，启动检查
     * @return
     */
    @GetMapping("/checkpreload.htm")
    public String checkload(){
        return "success";
    }

    /**
     * 动态追加 IP
     * @param req
     * @return
     */
    @PostMapping("/putIp")
    public String putIp(@Validated  @RequestBody IpReq req){
        log.info("putIp req:{}", JSON.toJSONString(req));
        List<String> ips = Arrays.asList(req.getIps().split(","));

        //redisTemplate.delete(req.getId());
        //ips.add("43.133.81.217:7860");

        ips = ips.stream().distinct().collect(Collectors.toList());
        log.info("ips stream:{}",JSON.toJSONString(ips));

        ListOperations<String, String> listOps = redisTemplate.opsForList();
        List<String> result = null;
        try{
            result = listOps.range(req.getId(), 0, -1);
        }catch (Exception e){
            log.error(e.getMessage(),e);
        }
        if(result == null){
            result = new ArrayList<>();
        }
        result.addAll(ips);

        result = result.stream().distinct().collect(Collectors.toList());

        redisTemplate.delete(req.getId());
        listOps.leftPushAll(req.getId(),result);
        result = listOps.range(req.getId(), 0, -1);
        return "putIp success,result:"+ JSON.toJSONString(result);
    }

    @GetMapping("/clearIp")
    public String clearIp(){
        //按路由 清理redis
        List<RouteDefinition> routes = gatewayProperties.getRoutes();
        routes.stream().forEach(t->{
            String routeId = t.getId();
            log.info("routeId:"+ routeId);
            allDel(routeId);
            redisTemplate.delete(routeId);
        });
        GatewayFilter.KEYS.clear();
        return "clearIp success";
    }

    @GetMapping("/getWeight")
    public String getWeight(){
        //按路由 清理redis
        Map<String, Long> map = GatewayFilter.KEYS;
        String str = JSON.toJSONString(map);
        log.info("getWeight:{}",str);
        return str;
    }


    @PostMapping("/clearByid")
    public String clearByid(@Validated  @RequestBody IpReq req){
        log.info("clearByid req:{}", JSON.toJSONString(req));
        List<String> ips = Arrays.asList(req.getIps().split(","));
        //TODO 处理 list remove
        ListOperations<String, String> listOps = redisTemplate.opsForList();
        List<String> result = listOps.range(req.getId(), 0, -1);
        if(result == null){
            result = new ArrayList<>();
        }
        String key = null;
        String routeId = req.getId();
        for(String ip : ips){
            key = routeId +"_";
            key = key + ip ;
            log.info("key:{}",key);
            redisTemplate.delete(key);
            listOps.remove(routeId,0,ip);
        }
        GatewayFilter.KEYS.clear();
        return "clearByid success";
    }

    /**
     * 全量删除缓存
     * @param routeId 可以传一个值 或多个
     */
    private void allDel(String routeId) {
        ListOperations<String, String> listOps = redisTemplate.opsForList();
        List<String> result = listOps.range(routeId, 0, -1);
        if(result == null){
            result = new ArrayList<>();
        }
        String key = null;
        for(String ip : result){
            key = routeId +"_";
            key = key + ip ;
            log.info("key:{}",key);
            redisTemplate.delete(key);
            //listOps.remove(routeId,0,ip);
        }
    }

}
